package com.jetson.centercontrol;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import org.json.JSONException;
import org.json.JSONObject;
import org.webrtc.DataChannel;
import org.webrtc.DefaultVideoDecoderFactory;
import org.webrtc.DefaultVideoEncoderFactory;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.SessionDescription;
import org.webrtc.SurfaceViewRenderer;

import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "WebRTC_MainActivity";
    
    // 服务器地址，请替换为您的WebRTC服务器URL
    private static final String SERVER_URL = "http://192.168.1.100:3000"; // 替换为实际服务器地址
    
    // UI 元素
    private EditText roomIdInput;
    private Button joinRoomBtn;
    private TextView connectionStatus;
    private SurfaceViewRenderer remoteVideoView;
    
    // WebRTC & Socket.io 组件
    private Socket socket;
    private PeerConnectionFactory peerConnectionFactory;
    private PeerConnection peerConnection;
    private EglBase eglBase;
    
    // 房间和用户ID
    private String roomId;
    private String userId;
    private String sharingUserId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 生成随机用户ID
        userId = UUID.randomUUID().toString().substring(0, 8);
        Log.d(TAG, "用户ID: " + userId);
        
        // 初始化UI组件
        initializeUI();
        
        // 初始化WebRTC
        initializeWebRTC();
        
        // 连接到Socket.io服务器
        connectToSocketServer();
        
        // 设置事件监听器
        setupEventListeners();
    }
    
    private void initializeUI() {
        roomIdInput = findViewById(R.id.room_id_input);
        joinRoomBtn = findViewById(R.id.join_room_btn);
        connectionStatus = findViewById(R.id.connection_status);
        remoteVideoView = findViewById(R.id.remote_video_view);
        
        // 默认设置为"123456789"
        roomIdInput.setText("123456789");
    }
    
    private void initializeWebRTC() {
        // 创建EglBase实例（用于视频渲染）
        eglBase = EglBase.create();
        
        // 初始化PeerConnectionFactory
        PeerConnectionFactory.InitializationOptions initOptions = 
                PeerConnectionFactory.InitializationOptions.builder(this)
                        .createInitializationOptions();
        PeerConnectionFactory.initialize(initOptions);
        
        // 创建PeerConnectionFactory
        PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
        DefaultVideoEncoderFactory videoEncoderFactory = 
                new DefaultVideoEncoderFactory(eglBase.getEglBaseContext(), true, true);
        DefaultVideoDecoderFactory videoDecoderFactory = 
                new DefaultVideoDecoderFactory(eglBase.getEglBaseContext());
                
        peerConnectionFactory = PeerConnectionFactory.builder()
                .setOptions(options)
                .setVideoEncoderFactory(videoEncoderFactory)
                .setVideoDecoderFactory(videoDecoderFactory)
                .createPeerConnectionFactory();
                
        // 初始化SurfaceViewRenderer
        remoteVideoView.init(eglBase.getEglBaseContext(), null);
        remoteVideoView.setEnableHardwareScaler(true);
        remoteVideoView.setMirror(true);
    }
    
    private void connectToSocketServer() {
        try {
            socket = IO.socket(SERVER_URL);
            
            socket.on(Socket.EVENT_CONNECT, args -> {
                Log.d(TAG, "已连接到Socket.io服务器");
                runOnUiThread(() -> connectionStatus.setText("已连接到服务器"));
            });
            
            socket.on(Socket.EVENT_DISCONNECT, args -> {
                Log.d(TAG, "与Socket.io服务器断开连接");
                runOnUiThread(() -> {
                    connectionStatus.setText("已断开连接");
                    closePeerConnection();
                });
            });
            
            socket.on(Socket.EVENT_CONNECT_ERROR, args -> {
                Log.e(TAG, "Socket.io连接错误: " + args[0]);
                runOnUiThread(() -> {
                    connectionStatus.setText("连接错误");
                    Toast.makeText(this, "连接服务器失败", Toast.LENGTH_SHORT).show();
                });
            });
            
            // 自定义事件监听器
            socket.on("user-started-sharing", args -> {
                String startSharingUserId = (String) args[0];
                Log.d(TAG, "用户开始共享屏幕: " + startSharingUserId);
                sharingUserId = startSharingUserId;
                runOnUiThread(() -> connectionStatus.setText("正在连接到共享画面..."));
            });
            
            socket.on("user-stopped-sharing", args -> {
                String stopSharingUserId = (String) args[0];
                Log.d(TAG, "用户停止共享屏幕: " + stopSharingUserId);
                if (stopSharingUserId.equals(sharingUserId)) {
                    runOnUiThread(() -> {
                        connectionStatus.setText("共享已结束");
                        remoteVideoView.setVisibility(View.GONE);
                    });
                    closePeerConnection();
                }
            });
            
            socket.on("offer", args -> {
                try {
                    String senderId = (String) args[0];
                    JSONObject offerData = (JSONObject) args[1];
                    
                    // 检查offer是否发给我
                    String targetId = offerData.getString("targetUserId");
                    if (!targetId.equals(userId)) return;
                    
                    Log.d(TAG, "收到offer: " + offerData);
                    SessionDescription offerSdp = new SessionDescription(
                            SessionDescription.Type.OFFER,
                            offerData.getJSONObject("offer").getString("sdp")
                    );
                    
                    handleOffer(senderId, offerSdp);
                    
                } catch (JSONException e) {
                    Log.e(TAG, "解析offer失败", e);
                }
            });
            
            socket.on("ice-candidate", args -> {
                try {
                    String senderId = (String) args[0];
                    JSONObject candidateData = (JSONObject) args[1];
                    
                    // 检查候选是否发给我
                    String targetId = candidateData.getString("targetUserId");
                    if (!targetId.equals(userId)) return;
                    
                    JSONObject candidate = candidateData.getJSONObject("candidate");
                    Log.d(TAG, "收到ICE候选: " + candidate);
                    
                    IceCandidate iceCandidate = new IceCandidate(
                            candidate.getString("sdpMid"),
                            candidate.getInt("sdpMLineIndex"),
                            candidate.getString("candidate")
                    );
                    
                    if (peerConnection != null) {
                        peerConnection.addIceCandidate(iceCandidate);
                    }
                    
                } catch (JSONException e) {
                    Log.e(TAG, "解析ICE候选失败", e);
                }
            });
            
            socket.connect();
            
        } catch (URISyntaxException e) {
            Log.e(TAG, "Socket.io URL语法错误", e);
            Toast.makeText(this, "服务器URL无效", Toast.LENGTH_SHORT).show();
        }
    }
    
    private void setupEventListeners() {
        joinRoomBtn.setOnClickListener(v -> {
            roomId = roomIdInput.getText().toString().trim();
            if (roomId.isEmpty()) {
                Toast.makeText(this, "请输入房间ID", Toast.LENGTH_SHORT).show();
                return;
            }
            
            joinRoom(roomId);
        });
    }
    
    private void joinRoom(String roomId) {
        if (socket != null && socket.connected()) {
            socket.emit("join-room", roomId, userId);
            Log.d(TAG, "加入房间: " + roomId);
            connectionStatus.setText("已加入房间: " + roomId);
            joinRoomBtn.setEnabled(false);
            roomIdInput.setEnabled(false);
        } else {
            Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
        }
    }
    
    private void createPeerConnection() {
        // 如果已存在连接则关闭
        closePeerConnection();
        
        List<PeerConnection.IceServer> iceServers = new ArrayList<>();
        iceServers.add(PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer());
        
        PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers);
        rtcConfig.sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN;
        
        peerConnection = peerConnectionFactory.createPeerConnection(rtcConfig, new PeerConnection.Observer() {
            @Override
            public void onSignalingChange(PeerConnection.SignalingState signalingState) {
                Log.d(TAG, "onSignalingChange: " + signalingState);
            }

            @Override
            public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
                Log.d(TAG, "onIceConnectionChange: " + iceConnectionState);
                if (iceConnectionState == PeerConnection.IceConnectionState.CONNECTED) {
                    runOnUiThread(() -> connectionStatus.setText("已连接到共享画面"));
                } else if (iceConnectionState == PeerConnection.IceConnectionState.DISCONNECTED ||
                           iceConnectionState == PeerConnection.IceConnectionState.FAILED) {
                    runOnUiThread(() -> connectionStatus.setText("连接已断开"));
                }
            }

            @Override
            public void onIceConnectionReceivingChange(boolean b) {
                Log.d(TAG, "onIceConnectionReceivingChange: " + b);
            }

            @Override
            public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {
                Log.d(TAG, "onIceGatheringChange: " + iceGatheringState);
            }

            @Override
            public void onIceCandidate(IceCandidate iceCandidate) {
                Log.d(TAG, "onIceCandidate: " + iceCandidate);
                // 发送ICE候选到对方
                try {
                    JSONObject candidateData = new JSONObject();
                    candidateData.put("targetUserId", sharingUserId);
                    
                    JSONObject candidate = new JSONObject();
                    candidate.put("sdpMid", iceCandidate.sdpMid);
                    candidate.put("sdpMLineIndex", iceCandidate.sdpMLineIndex);
                    candidate.put("candidate", iceCandidate.sdp);
                    
                    candidateData.put("candidate", candidate);
                    
                    socket.emit("ice-candidate", roomId, userId, candidateData);
                    
                } catch (JSONException e) {
                    Log.e(TAG, "发送ICE候选失败", e);
                }
            }

            @Override
            public void onIceCandidatesRemoved(IceCandidate[] iceCandidates) {
                Log.d(TAG, "onIceCandidatesRemoved");
            }

            @Override
            public void onAddStream(MediaStream mediaStream) {
                Log.d(TAG, "onAddStream: " + mediaStream.id());
                // 添加远程视频流到UI
                if (mediaStream.videoTracks.size() > 0) {
                    runOnUiThread(() -> {
                        mediaStream.videoTracks.get(0).addSink(remoteVideoView);
                        remoteVideoView.setVisibility(View.VISIBLE);
                    });
                }
            }

            @Override
            public void onRemoveStream(MediaStream mediaStream) {
                Log.d(TAG, "onRemoveStream: " + mediaStream.id());
            }

            @Override
            public void onDataChannel(DataChannel dataChannel) {
                Log.d(TAG, "onDataChannel: " + dataChannel.label());
            }

            @Override
            public void onRenegotiationNeeded() {
                Log.d(TAG, "onRenegotiationNeeded");
            }

            @Override
            public void onAddTrack(org.webrtc.RtpReceiver rtpReceiver, MediaStream[] mediaStreams) {
                Log.d(TAG, "onAddTrack");
            }
        });
    }
    
    private void handleOffer(String senderId, SessionDescription offerSdp) {
        sharingUserId = senderId;
        Log.d(TAG, "处理offer来自: " + senderId);
        
        runOnUiThread(() -> {
            // 创建PeerConnection
            createPeerConnection();
            
            if (peerConnection != null) {
                peerConnection.setRemoteDescription(new SdpObserver("setRemoteDescription") {
                    @Override
                    public void onSetSuccess() {
                        Log.d(TAG, "setRemoteDescription成功");
                        
                        // 创建应答(Answer)
                        MediaConstraints constraints = new MediaConstraints();
                        constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
                        
                        peerConnection.createAnswer(new SdpObserver("createAnswer") {
                            @Override
                            public void onCreateSuccess(SessionDescription sdp) {
                                Log.d(TAG, "创建answer成功");
                                
                                peerConnection.setLocalDescription(new SdpObserver("setLocalDescription") {
                                    @Override
                                    public void onSetSuccess() {
                                        Log.d(TAG, "setLocalDescription成功");
                                        
                                        // 发送应答到对方
                                        try {
                                            JSONObject answerData = new JSONObject();
                                            answerData.put("targetUserId", senderId);
                                            
                                            JSONObject answer = new JSONObject();
                                            answer.put("type", sdp.type.canonicalForm());
                                            answer.put("sdp", sdp.description);
                                            
                                            answerData.put("answer", answer);
                                            
                                            socket.emit("answer", roomId, userId, answerData);
                                            
                                        } catch (JSONException e) {
                                            Log.e(TAG, "发送answer失败", e);
                                        }
                                    }
                                }, sdp);
                            }
                        }, constraints);
                    }
                }, offerSdp);
            }
        });
    }
    
    private void closePeerConnection() {
        if (peerConnection != null) {
            peerConnection.close();
            peerConnection = null;
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        
        // 关闭连接
        closePeerConnection();
        
        // 断开Socket连接
        if (socket != null) {
            socket.disconnect();
            socket.close();
        }
        
        // 释放视图资源
        if (remoteVideoView != null) {
            remoteVideoView.release();
        }
        
        // 释放EglBase
        if (eglBase != null) {
            eglBase.release();
        }
    }
    
    // SdpObserver实现类
    private class SdpObserver implements org.webrtc.SdpObserver {
        private final String tag;
        
        public SdpObserver(String tag) {
            this.tag = tag;
        }
        
        @Override
        public void onCreateSuccess(SessionDescription sessionDescription) {
            Log.d(TAG, tag + ": onCreateSuccess");
        }
        
        @Override
        public void onSetSuccess() {
            Log.d(TAG, tag + ": onSetSuccess");
        }
        
        @Override
        public void onCreateFailure(String s) {
            Log.e(TAG, tag + ": onCreateFailure: " + s);
        }
        
        @Override
        public void onSetFailure(String s) {
            Log.e(TAG, tag + ": onSetFailure: " + s);
        }
    }
}